home *** CD-ROM | disk | FTP | other *** search
/ The Complete Utilities To…ka 501 Killer Utilities! / 501 Killer Utilities! (Macworld July 1995).cdr / Programming / OutOfPhase1.1 Source / OutOfPhase Folder / FilterSpec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-08  |  21.5 KB  |  725 lines  |  [TEXT/KAHL]

  1. /* FilterSpec.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "FilterSpec.h"
  31. #include "Memory.h"
  32. #include "Array.h"
  33. #include "LFOListSpecifier.h"
  34. #include "Envelope.h"
  35.  
  36.  
  37. struct OneFilterRec
  38.     {
  39.         /* what kind of filtering */
  40.         FilterTypes                    FilterType;
  41.         FilterScalings            FilterScaling;
  42.         FilterChannels            Channel;
  43.  
  44.         /* these controls only apply to the track effect, not the oscillator effect */
  45.         float                                Cutoff;
  46.         float                                CutoffAccent1;
  47.         float                                CutoffAccent2;
  48.         float                                CutoffAccent3;
  49.         float                                CutoffAccent4;
  50.         float                                Bandwidth;
  51.         float                                BandwidthAccent1;
  52.         float                                BandwidthAccent2;
  53.         float                                BandwidthAccent3;
  54.         float                                BandwidthAccent4;
  55.         float                                OutputMultiplier;
  56.         float                                OutputMultiplierAccent1;
  57.         float                                OutputMultiplierAccent2;
  58.         float                                OutputMultiplierAccent3;
  59.         float                                OutputMultiplierAccent4;
  60.  
  61.         /* these controls only apply to the oscillator effect, not the track effect */
  62.         EnvelopeRec*                CutoffEnvelope;
  63.         EnvelopeRec*                BandwidthEnvelope;
  64.         EnvelopeRec*                OutputEnvelope;
  65.         LFOListSpecRec*            CutoffLFO;
  66.         LFOListSpecRec*            BandwidthLFO;
  67.         LFOListSpecRec*            OutputLFO;
  68.     };
  69.  
  70.  
  71. struct FilterSpecRec
  72.     {
  73.         ArrayRec*                        List;
  74.     };
  75.  
  76.  
  77. /* create a new parallel filter specification */
  78. FilterSpecRec*        NewFilterSpec(void)
  79.     {
  80.         FilterSpecRec*    Filter;
  81.  
  82.         Filter = (FilterSpecRec*)AllocPtrCanFail(sizeof(FilterSpecRec),"FilterSpecRec");
  83.         if (Filter == NIL)
  84.             {
  85.              FailurePoint1:
  86.                 return NIL;
  87.             }
  88.         Filter->List = NewArray();
  89.         if (Filter->List == NIL)
  90.             {
  91.              FailurePoint2:
  92.                 ReleasePtr((char*)Filter);
  93.                 goto FailurePoint1;
  94.             }
  95.         return Filter;
  96.     }
  97.  
  98.  
  99. /* dispose of a filter specification */
  100. void                            DisposeFilterSpec(FilterSpecRec* Filter)
  101.     {
  102.         long                        Scan;
  103.         long                        Limit;
  104.  
  105.         CheckPtrExistence(Filter);
  106.         Limit = ArrayGetLength(Filter->List);
  107.         for (Scan = 0; Scan < Limit; Scan += 1)
  108.             {
  109.                 OneFilterRec*        FilterElement;
  110.  
  111.                 FilterElement = ArrayGetElement(Filter->List,Scan);
  112.                 DisposeEnvelope(FilterElement->CutoffEnvelope);
  113.                 DisposeEnvelope(FilterElement->BandwidthEnvelope);
  114.                 DisposeEnvelope(FilterElement->OutputEnvelope);
  115.                 DisposeLFOListSpecifier(FilterElement->CutoffLFO);
  116.                 DisposeLFOListSpecifier(FilterElement->BandwidthLFO);
  117.                 DisposeLFOListSpecifier(FilterElement->OutputLFO);
  118.                 ReleasePtr((char*)FilterElement);
  119.             }
  120.         DisposeArray(Filter->List);
  121.         ReleasePtr((char*)Filter);
  122.     }
  123.  
  124.  
  125. /* add a single filter to the list */
  126. MyBoolean                    AppendFilterToSpec(FilterSpecRec* Filter, OneFilterRec* Spec)
  127.     {
  128.         CheckPtrExistence(Filter);
  129.         CheckPtrExistence(Spec);
  130.         return ArrayAppendElement(Filter->List,Spec);
  131.     }
  132.  
  133.  
  134. /* get the number of filters */
  135. long                            GetNumFiltersInSpec(FilterSpecRec* Filter)
  136.     {
  137.         CheckPtrExistence(Filter);
  138.         return ArrayGetLength(Filter->List);
  139.     }
  140.  
  141.  
  142. /* get a filter type for the specified filter spec */
  143. FilterTypes                GetFilterType(FilterSpecRec* Filter, long Index)
  144.     {
  145.         OneFilterRec*        Spec;
  146.  
  147.         CheckPtrExistence(Filter);
  148.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  149.             PRERR(ForceAbort,"GetFilterType:  index out of range"));
  150.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  151.         CheckPtrExistence(Spec);
  152.         return Spec->FilterType;
  153.     }
  154.  
  155.  
  156. /* get which channel to apply a filter to */
  157. FilterChannels        GetFilterChannel(FilterSpecRec* Filter, long Index)
  158.     {
  159.         OneFilterRec*        Spec;
  160.  
  161.         CheckPtrExistence(Filter);
  162.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  163.             PRERR(ForceAbort,"GetFilterChannel:  index out of range"));
  164.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  165.         CheckPtrExistence(Spec);
  166.         return Spec->Channel;
  167.     }
  168.  
  169.  
  170. float                            GetFilterCutoff(FilterSpecRec* Filter, long Index)
  171.     {
  172.         OneFilterRec*        Spec;
  173.  
  174.         CheckPtrExistence(Filter);
  175.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  176.             PRERR(ForceAbort,"GetFilterCutoff:  index out of range"));
  177.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  178.         CheckPtrExistence(Spec);
  179.         return Spec->Cutoff;
  180.     }
  181.  
  182.  
  183. float                            GetFilterCutoffAccent1(FilterSpecRec* Filter, long Index)
  184.     {
  185.         OneFilterRec*        Spec;
  186.  
  187.         CheckPtrExistence(Filter);
  188.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  189.             PRERR(ForceAbort,"GetFilterCutoffAccent1:  index out of range"));
  190.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  191.         CheckPtrExistence(Spec);
  192.         return Spec->CutoffAccent1;
  193.     }
  194.  
  195.  
  196. float                            GetFilterCutoffAccent2(FilterSpecRec* Filter, long Index)
  197.     {
  198.         OneFilterRec*        Spec;
  199.  
  200.         CheckPtrExistence(Filter);
  201.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  202.             PRERR(ForceAbort,"GetFilterCutoffAccent2:  index out of range"));
  203.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  204.         CheckPtrExistence(Spec);
  205.         return Spec->CutoffAccent2;
  206.     }
  207.  
  208.  
  209. float                            GetFilterCutoffAccent3(FilterSpecRec* Filter, long Index)
  210.     {
  211.         OneFilterRec*        Spec;
  212.  
  213.         CheckPtrExistence(Filter);
  214.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  215.             PRERR(ForceAbort,"GetFilterCutoffAccent3:  index out of range"));
  216.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  217.         CheckPtrExistence(Spec);
  218.         return Spec->CutoffAccent3;
  219.     }
  220.  
  221.  
  222. float                            GetFilterCutoffAccent4(FilterSpecRec* Filter, long Index)
  223.     {
  224.         OneFilterRec*        Spec;
  225.  
  226.         CheckPtrExistence(Filter);
  227.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  228.             PRERR(ForceAbort,"GetFilterCutoffAccent4:  index out of range"));
  229.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  230.         CheckPtrExistence(Spec);
  231.         return Spec->CutoffAccent4;
  232.     }
  233.  
  234.  
  235. float                            GetFilterBandwidth(FilterSpecRec* Filter, long Index)
  236.     {
  237.         OneFilterRec*        Spec;
  238.  
  239.         CheckPtrExistence(Filter);
  240.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  241.             PRERR(ForceAbort,"GetFilterBandwidth:  index out of range"));
  242.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  243.         CheckPtrExistence(Spec);
  244.         return Spec->Bandwidth;
  245.     }
  246.  
  247.  
  248. float                            GetFilterBandwidthAccent1(FilterSpecRec* Filter, long Index)
  249.     {
  250.         OneFilterRec*        Spec;
  251.  
  252.         CheckPtrExistence(Filter);
  253.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  254.             PRERR(ForceAbort,"GetFilterBandwidthAccent1:  index out of range"));
  255.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  256.         CheckPtrExistence(Spec);
  257.         return Spec->BandwidthAccent1;
  258.     }
  259.  
  260.  
  261. float                            GetFilterBandwidthAccent2(FilterSpecRec* Filter, long Index)
  262.     {
  263.         OneFilterRec*        Spec;
  264.  
  265.         CheckPtrExistence(Filter);
  266.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  267.             PRERR(ForceAbort,"GetFilterBandwidthAccent2:  index out of range"));
  268.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  269.         CheckPtrExistence(Spec);
  270.         return Spec->BandwidthAccent2;
  271.     }
  272.  
  273.  
  274. float                            GetFilterBandwidthAccent3(FilterSpecRec* Filter, long Index)
  275.     {
  276.         OneFilterRec*        Spec;
  277.  
  278.         CheckPtrExistence(Filter);
  279.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  280.             PRERR(ForceAbort,"GetFilterBandwidthAccent3:  index out of range"));
  281.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  282.         CheckPtrExistence(Spec);
  283.         return Spec->BandwidthAccent3;
  284.     }
  285.  
  286.  
  287. float                            GetFilterBandwidthAccent4(FilterSpecRec* Filter, long Index)
  288.     {
  289.         OneFilterRec*        Spec;
  290.  
  291.         CheckPtrExistence(Filter);
  292.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  293.             PRERR(ForceAbort,"GetFilterBandwidthAccent4:  index out of range"));
  294.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  295.         CheckPtrExistence(Spec);
  296.         return Spec->BandwidthAccent4;
  297.     }
  298.  
  299.  
  300. FilterScalings        GetFilterScalingMode(FilterSpecRec* Filter, long Index)
  301.     {
  302.         OneFilterRec*        Spec;
  303.  
  304.         CheckPtrExistence(Filter);
  305.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  306.             PRERR(ForceAbort,"GetFilterScalingMode:  index out of range"));
  307.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  308.         CheckPtrExistence(Spec);
  309.         return Spec->FilterScaling;
  310.     }
  311.  
  312.  
  313. float                            GetFilterOutputMultiplier(FilterSpecRec* Filter, long Index)
  314.     {
  315.         OneFilterRec*        Spec;
  316.  
  317.         CheckPtrExistence(Filter);
  318.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  319.             PRERR(ForceAbort,"GetFilterOutputMultiplier:  index out of range"));
  320.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  321.         CheckPtrExistence(Spec);
  322.         return Spec->OutputMultiplier;
  323.     }
  324.  
  325.  
  326. float                            GetFilterOutputMultiplierAccent1(FilterSpecRec* Filter, long Index)
  327.     {
  328.         OneFilterRec*        Spec;
  329.  
  330.         CheckPtrExistence(Filter);
  331.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  332.             PRERR(ForceAbort,"GetFilterOutputMultiplierAccent1:  index out of range"));
  333.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  334.         CheckPtrExistence(Spec);
  335.         return Spec->OutputMultiplierAccent1;
  336.     }
  337.  
  338.  
  339. float                            GetFilterOutputMultiplierAccent2(FilterSpecRec* Filter, long Index)
  340.     {
  341.         OneFilterRec*        Spec;
  342.  
  343.         CheckPtrExistence(Filter);
  344.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  345.             PRERR(ForceAbort,"GetFilterOutputMultiplierAccent2:  index out of range"));
  346.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  347.         CheckPtrExistence(Spec);
  348.         return Spec->OutputMultiplierAccent2;
  349.     }
  350.  
  351.  
  352. float                            GetFilterOutputMultiplierAccent3(FilterSpecRec* Filter, long Index)
  353.     {
  354.         OneFilterRec*        Spec;
  355.  
  356.         CheckPtrExistence(Filter);
  357.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  358.             PRERR(ForceAbort,"GetFilterOutputMultiplierAccent3:  index out of range"));
  359.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  360.         CheckPtrExistence(Spec);
  361.         return Spec->OutputMultiplierAccent3;
  362.     }
  363.  
  364.  
  365. float                            GetFilterOutputMultiplierAccent4(FilterSpecRec* Filter, long Index)
  366.     {
  367.         OneFilterRec*        Spec;
  368.  
  369.         CheckPtrExistence(Filter);
  370.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  371.             PRERR(ForceAbort,"GetFilterOutputMultiplierAccent4:  index out of range"));
  372.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  373.         CheckPtrExistence(Spec);
  374.         return Spec->OutputMultiplierAccent4;
  375.     }
  376.  
  377.  
  378. struct EnvelopeRec*    GetFilterCutoffEnvelope(FilterSpecRec* Filter, long Index)
  379.     {
  380.         OneFilterRec*        Spec;
  381.  
  382.         CheckPtrExistence(Filter);
  383.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  384.             PRERR(ForceAbort,"GetFilterCutoffEnvelope:  index out of range"));
  385.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  386.         CheckPtrExistence(Spec);
  387.         return Spec->CutoffEnvelope;
  388.     }
  389.  
  390.  
  391. struct EnvelopeRec*    GetFilterBandwidthEnvelope(FilterSpecRec* Filter, long Index)
  392.     {
  393.         OneFilterRec*        Spec;
  394.  
  395.         CheckPtrExistence(Filter);
  396.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  397.             PRERR(ForceAbort,"GetFilterBandwidthEnvelope:  index out of range"));
  398.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  399.         CheckPtrExistence(Spec);
  400.         return Spec->BandwidthEnvelope;
  401.     }
  402.  
  403.  
  404. struct EnvelopeRec*    GetFilterOutputEnvelope(FilterSpecRec* Filter, long Index)
  405.     {
  406.         OneFilterRec*        Spec;
  407.  
  408.         CheckPtrExistence(Filter);
  409.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  410.             PRERR(ForceAbort,"GetFilterOutputEnvelope:  index out of range"));
  411.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  412.         CheckPtrExistence(Spec);
  413.         return Spec->OutputEnvelope;
  414.     }
  415.  
  416.  
  417. struct LFOListSpecRec*    GetFilterCutoffLFO(FilterSpecRec* Filter, long Index)
  418.     {
  419.         OneFilterRec*        Spec;
  420.  
  421.         CheckPtrExistence(Filter);
  422.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  423.             PRERR(ForceAbort,"GetFilterCutoffLFO:  index out of range"));
  424.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  425.         CheckPtrExistence(Spec);
  426.         return Spec->CutoffLFO;
  427.     }
  428.  
  429.  
  430. struct LFOListSpecRec*    GetFilterBandwidthLFO(FilterSpecRec* Filter, long Index)
  431.     {
  432.         OneFilterRec*        Spec;
  433.  
  434.         CheckPtrExistence(Filter);
  435.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  436.             PRERR(ForceAbort,"GetFilterBandwidthLFO:  index out of range"));
  437.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  438.         CheckPtrExistence(Spec);
  439.         return Spec->BandwidthLFO;
  440.     }
  441.  
  442.  
  443. struct LFOListSpecRec*    GetFilterOutputLFO(FilterSpecRec* Filter, long Index)
  444.     {
  445.         OneFilterRec*        Spec;
  446.  
  447.         CheckPtrExistence(Filter);
  448.         ERROR((Index < 0) || (Index >= GetNumFiltersInSpec(Filter)),
  449.             PRERR(ForceAbort,"GetFilterOutputLFO:  index out of range"));
  450.         Spec = (OneFilterRec*)ArrayGetElement(Filter->List,Index);
  451.         CheckPtrExistence(Spec);
  452.         return Spec->OutputLFO;
  453.     }
  454.  
  455.  
  456. /* create a new filter specification record */
  457. OneFilterRec*            NewSingleFilterSpec(FilterTypes FilterType)
  458.     {
  459.         OneFilterRec*        Spec;
  460.  
  461.         ERROR((FilterType != eFilterNull)
  462.             && (FilterType != eFilterFirstOrderLowpass)
  463.             && (FilterType != eFilterFirstOrderHighpass)
  464.             && (FilterType != eFilterSecondOrderResonant)
  465.             && (FilterType != eFilterSecondOrderZero)
  466.             && (FilterType != eFilterButterworthLowpass)
  467.             && (FilterType != eFilterButterworthHighpass)
  468.             && (FilterType != eFilterButterworthBandpass)
  469.             && (FilterType != eFilterButterworthBandreject),PRERR(ForceAbort,
  470.             "NewSingleFilterSpec:  unknown filter type"));
  471.         Spec = (OneFilterRec*)AllocPtrCanFail(sizeof(OneFilterRec),"OneFilterRec");
  472.         if (Spec == NIL)
  473.             {
  474.              FailurePoint1:
  475.                 return NIL;
  476.             }
  477.         Spec->CutoffEnvelope = NewEnvelope();
  478.         if (Spec->CutoffEnvelope == NIL)
  479.             {
  480.              FailurePoint2:
  481.                 ReleasePtr((char*)Spec);
  482.                 goto FailurePoint1;
  483.             }
  484.         Spec->BandwidthEnvelope = NewEnvelope();
  485.         if (Spec->BandwidthEnvelope == NIL)
  486.             {
  487.              FailurePoint3:
  488.                 DisposeEnvelope(Spec->CutoffEnvelope);
  489.                 goto FailurePoint2;
  490.             }
  491.         Spec->OutputEnvelope = NewEnvelope();
  492.         if (Spec->OutputEnvelope == NIL)
  493.             {
  494.              FailurePoint4:
  495.                 DisposeEnvelope(Spec->BandwidthEnvelope);
  496.                 goto FailurePoint3;
  497.             }
  498.         Spec->CutoffLFO = NewLFOListSpecifier();
  499.         if (Spec->CutoffLFO == NIL)
  500.             {
  501.              FailurePoint5:
  502.                 DisposeEnvelope(Spec->OutputEnvelope);
  503.                 goto FailurePoint4;
  504.             }
  505.         Spec->BandwidthLFO = NewLFOListSpecifier();
  506.         if (Spec->BandwidthLFO == NIL)
  507.             {
  508.              FailurePoint6:
  509.                 DisposeLFOListSpecifier(Spec->CutoffLFO);
  510.                 goto FailurePoint5;
  511.             }
  512.         Spec->OutputLFO = NewLFOListSpecifier();
  513.         if (Spec->OutputLFO == NIL)
  514.             {
  515.              FailurePoint7:
  516.                 DisposeLFOListSpecifier(Spec->BandwidthLFO);
  517.                 goto FailurePoint6;
  518.             }
  519.         Spec->FilterType = FilterType;
  520.         Spec->FilterScaling = eFilterDefaultScaling;
  521.         Spec->Channel = eFilterBoth;
  522.         Spec->Cutoff = 0;
  523.         Spec->CutoffAccent1 = 0;
  524.         Spec->CutoffAccent2 = 0;
  525.         Spec->CutoffAccent3 = 0;
  526.         Spec->CutoffAccent4 = 0;
  527.         Spec->Bandwidth = 0;
  528.         Spec->BandwidthAccent1 = 0;
  529.         Spec->BandwidthAccent2 = 0;
  530.         Spec->BandwidthAccent3 = 0;
  531.         Spec->BandwidthAccent4 = 0;
  532.         Spec->OutputMultiplier = 1;
  533.         Spec->OutputMultiplierAccent1 = 0;
  534.         Spec->OutputMultiplierAccent2 = 0;
  535.         Spec->OutputMultiplierAccent3 = 0;
  536.         Spec->OutputMultiplierAccent4 = 0;
  537.         return Spec;
  538.     }
  539.  
  540.  
  541. /* dispose of a single filter specification record */
  542. void                            DisposeSingleFilterSpec(OneFilterRec* Spec)
  543.     {
  544.         CheckPtrExistence(Spec);
  545.         DisposeEnvelope(Spec->CutoffEnvelope);
  546.         DisposeEnvelope(Spec->BandwidthEnvelope);
  547.         DisposeEnvelope(Spec->OutputEnvelope);
  548.         DisposeLFOListSpecifier(Spec->CutoffLFO);
  549.         DisposeLFOListSpecifier(Spec->BandwidthLFO);
  550.         DisposeLFOListSpecifier(Spec->OutputLFO);
  551.         ReleasePtr((char*)Spec);
  552.     }
  553.  
  554.  
  555. void                            SetSingleFilterCutoff(OneFilterRec* Spec, float Cutoff)
  556.     {
  557.         CheckPtrExistence(Spec);
  558.         Spec->Cutoff = Cutoff;
  559.     }
  560.  
  561.  
  562. void                            SetSingleFilterCutoffAccent1(OneFilterRec* Spec, float Accent1)
  563.     {
  564.         CheckPtrExistence(Spec);
  565.         Spec->CutoffAccent1 = Accent1;
  566.     }
  567.  
  568.  
  569. void                            SetSingleFilterCutoffAccent2(OneFilterRec* Spec, float Accent2)
  570.     {
  571.         CheckPtrExistence(Spec);
  572.         Spec->CutoffAccent2 = Accent2;
  573.     }
  574.  
  575.  
  576. void                            SetSingleFilterCutoffAccent3(OneFilterRec* Spec, float Accent3)
  577.     {
  578.         CheckPtrExistence(Spec);
  579.         Spec->CutoffAccent3 = Accent3;
  580.     }
  581.  
  582.  
  583. void                            SetSingleFilterCutoffAccent4(OneFilterRec* Spec, float Accent4)
  584.     {
  585.         CheckPtrExistence(Spec);
  586.         Spec->CutoffAccent4 = Accent4;
  587.     }
  588.  
  589.  
  590. void                            SetSingleFilterBandwidth(OneFilterRec* Spec, float Bandwidth)
  591.     {
  592.         CheckPtrExistence(Spec);
  593.         ERROR((Spec->FilterType != eFilterSecondOrderResonant)
  594.             && (Spec->FilterType != eFilterSecondOrderZero)
  595.             && (Spec->FilterType != eFilterButterworthBandpass)
  596.             && (Spec->FilterType != eFilterButterworthBandreject),
  597.             PRERR(ForceAbort,"SetSingleFilterBandwidth:  filter type has no bandwidth parameter"));
  598.         Spec->Bandwidth = Bandwidth;
  599.     }
  600.  
  601.  
  602. void                            SetSingleFilterBandwidthAccent1(OneFilterRec* Spec, float Accent1)
  603.     {
  604.         CheckPtrExistence(Spec);
  605.         ERROR((Spec->FilterType != eFilterSecondOrderResonant)
  606.             && (Spec->FilterType != eFilterSecondOrderZero)
  607.             && (Spec->FilterType != eFilterButterworthBandpass)
  608.             && (Spec->FilterType != eFilterButterworthBandreject),
  609.             PRERR(ForceAbort,"SetSingleFilterBandwidthAccent1:  filter type has no bandwidth parameter"));
  610.         Spec->BandwidthAccent1 = Accent1;
  611.     }
  612.  
  613.  
  614. void                            SetSingleFilterBandwidthAccent2(OneFilterRec* Spec, float Accent2)
  615.     {
  616.         CheckPtrExistence(Spec);
  617.         ERROR((Spec->FilterType != eFilterSecondOrderResonant)
  618.             && (Spec->FilterType != eFilterSecondOrderZero)
  619.             && (Spec->FilterType != eFilterButterworthBandpass)
  620.             && (Spec->FilterType != eFilterButterworthBandreject),
  621.             PRERR(ForceAbort,"SetSingleFilterBandwidthAccent2:  filter type has no bandwidth parameter"));
  622.         Spec->BandwidthAccent2 = Accent2;
  623.     }
  624.  
  625.  
  626. void                            SetSingleFilterBandwidthAccent3(OneFilterRec* Spec, float Accent3)
  627.     {
  628.         CheckPtrExistence(Spec);
  629.         ERROR((Spec->FilterType != eFilterSecondOrderResonant)
  630.             && (Spec->FilterType != eFilterSecondOrderZero)
  631.             && (Spec->FilterType != eFilterButterworthBandpass)
  632.             && (Spec->FilterType != eFilterButterworthBandreject),
  633.             PRERR(ForceAbort,"SetSingleFilterBandwidthAccent3:  filter type has no bandwidth parameter"));
  634.         Spec->BandwidthAccent3 = Accent3;
  635.     }
  636.  
  637.  
  638. void                            SetSingleFilterBandwidthAccent4(OneFilterRec* Spec, float Accent4)
  639.     {
  640.         CheckPtrExistence(Spec);
  641.         ERROR((Spec->FilterType != eFilterSecondOrderResonant)
  642.             && (Spec->FilterType != eFilterSecondOrderZero)
  643.             && (Spec->FilterType != eFilterButterworthBandpass)
  644.             && (Spec->FilterType != eFilterButterworthBandreject),
  645.             PRERR(ForceAbort,"SetSingleFilterBandwidthAccent4:  filter type has no bandwidth parameter"));
  646.         Spec->BandwidthAccent4 = Accent4;
  647.     }
  648.  
  649.  
  650. /* set filter scaling mode */
  651. void                            SetSingleFilterScalingMode(OneFilterRec* Spec, FilterScalings Scaling)
  652.     {
  653.         CheckPtrExistence(Spec);
  654.         switch (Spec->FilterType)
  655.             {
  656.                 default:
  657.                     EXECUTE(PRERR(ForceAbort,"SetSingleFilterScalingMode:  bad filter type"));
  658.                     break;
  659.                 case eFilterNull:
  660.                 case eFilterFirstOrderLowpass:
  661.                 case eFilterFirstOrderHighpass:
  662.                 case eFilterButterworthLowpass:
  663.                 case eFilterButterworthHighpass:
  664.                 case eFilterButterworthBandpass:
  665.                 case eFilterButterworthBandreject:
  666.                     ERROR(Scaling != eFilterDefaultScaling,PRERR(ForceAbort,
  667.                         "SetSingleFilterScalingMode:  invalid scaling"));
  668.                     break;
  669.                 case eFilterSecondOrderResonant:
  670.                     ERROR((Scaling != eFilterDefaultScaling)
  671.                         && (Scaling != eFilterResonMidbandGain1)
  672.                         && (Scaling != eFilterResonNoiseGain1),
  673.                         PRERR(ForceAbort,"SetSingleFilterScalingMode:  invalid scaling"));
  674.                     break;
  675.                 case eFilterSecondOrderZero:
  676.                     ERROR((Scaling != eFilterDefaultScaling) && (Scaling != eFilterZeroGain1),
  677.                         PRERR(ForceAbort,"SetSingleFilterScalingMode:  invalid scaling"));
  678.                     break;
  679.             }
  680.         Spec->FilterScaling = Scaling;
  681.     }
  682.  
  683.  
  684. /* set filter channel */
  685. void                            SetSingleFilterChannel(OneFilterRec* Spec, FilterChannels Channel)
  686.     {
  687.         CheckPtrExistence(Spec);
  688.         Spec->Channel = Channel;
  689.     }
  690.  
  691.  
  692. void                            SetSingleFilterOutputMultiplier(OneFilterRec* Spec, float Output)
  693.     {
  694.         CheckPtrExistence(Spec);
  695.         Spec->OutputMultiplier = Output;
  696.     }
  697.  
  698.  
  699. void                            SetSingleFilterOutputMultiplierAccent1(OneFilterRec* Spec, float Accent1)
  700.     {
  701.         CheckPtrExistence(Spec);
  702.         Spec->OutputMultiplierAccent1 = Accent1;
  703.     }
  704.  
  705.  
  706. void                            SetSingleFilterOutputMultiplierAccent2(OneFilterRec* Spec, float Accent2)
  707.     {
  708.         CheckPtrExistence(Spec);
  709.         Spec->OutputMultiplierAccent2 = Accent2;
  710.     }
  711.  
  712.  
  713. void                            SetSingleFilterOutputMultiplierAccent3(OneFilterRec* Spec, float Accent3)
  714.     {
  715.         CheckPtrExistence(Spec);
  716.         Spec->OutputMultiplierAccent3 = Accent3;
  717.     }
  718.  
  719.  
  720. void                            SetSingleFilterOutputMultiplierAccent4(OneFilterRec* Spec, float Accent4)
  721.     {
  722.         CheckPtrExistence(Spec);
  723.         Spec->OutputMultiplierAccent4 = Accent4;
  724.     }
  725.